package com.github.ilioili.justdoit.components.fragment;

import android.graphics.Paint;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.github.ilioili.justdoit.R;
import com.github.ilioili.justdoit.components.activity.CreateOrModifyActivity;
import com.github.ilioili.justdoit.components.activity.DetailActivity;
import com.github.ilioili.justdoit.components.activity.PickDateActivity;
import com.github.ilioili.justdoit.components.activity.PickTimeActivity;
import com.github.ilioili.justdoit.model.dao.ScheduleEventDao;
import com.github.ilioili.justdoit.model.pojo.ScheduleEvent;
import com.github.ilioili.justdoit.components.receiver.AlarmReceiver;
import com.github.ilioili.justdoit.util.CompatUtil;
import com.github.ilioili.justdoit.util.DateUtil;
import com.github.ilioili.justdoit.util.LanguageUtil;
import com.github.ilioili.justdoit.widget.SatelliteView;
import com.github.ilioili.justdoit.widget.SlideListItemWrapper;
import com.github.ilioili.justdoit.widget.WatchTimePicker;
import com.taihe.template.base.BaseFragment;
import com.taihe.template.base.injection.Id;
import com.taihe.template.base.injection.InjectionUtil;
import com.taihe.template.base.util.SizeUtil;
import com.taihe.template.base.util.ToastUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hantuo on 16/5/15.
 */
public class QuadrantScheduleEventListFragment extends BaseFragment {

    public static final String BUNDLE_KEY_TYPE = "TYPE";
    private RecyclerView recyclerView;
    private List<ScheduleEvent> dataList = new ArrayList<>();
    private SatelliteMenu satelliteMenu;

    private SlideListItemWrapper slideListItemWrapper;
    private Type type;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        initRecyclerView();
        type = Type.readType(getArguments().getInt(BUNDLE_KEY_TYPE));
        return recyclerView;
    }

    private void initRecyclerView() {
        if (null == recyclerView) {
            recyclerView = new RecyclerView(getContext());
            recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
            recyclerView.setHasFixedSize(true);
            recyclerView.setAdapter(new RecyclerView.Adapter<Holder>() {

                @Override
                public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
                    View view = LayoutInflater.from(getContext()).inflate(R.layout.arrange_to_do_item, parent, false);
                    return new Holder(view);
                }

                @Override
                public void onBindViewHolder(Holder holder, int position) {
                    ScheduleEvent dataItem = dataList.get(position);
                    holder.tvName.setText(dataItem.name);
                    holder.vFirstView.setTag(dataItem);
                    holder.itemView.setTag(dataItem);
                    holder.tvName.setTag(dataItem);
                    holder.btnDelete.setTag(dataItem);
                    holder.btnComplete.setTag(dataItem);
                    holder.btnUndo.setTag(dataItem);
                    holder.btnArrange.setTag(dataItem);
                    holder.btnEditRoutine.setTag(dataItem);
                    holder.btnAlarm.setTag(dataItem);

                    if (dataItem.isComplete) {
                        holder.tvName.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
                        holder.tvName.setTextColor(CompatUtil.getColor(getContext(), R.color.font_gray));
                        holder.tvSub.setTextColor(CompatUtil.getColor(getContext(), R.color.font_gray));
                        setGone(holder.btnComplete, holder.btnAlarm, holder.btnArrange, holder.btnDelete, holder.btnEditRoutine);
                        setVisiable(holder.btnUndo);
                        CompatUtil.setFilterWithColorRes((ImageView) holder.btnComplete, R.color.font_gray);
                    } else {
                        holder.tvName.getPaint().setFlags(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
                        setVisiable(holder.btnComplete, holder.btnAlarm, holder.btnArrange, holder.btnDelete, holder.btnEditRoutine);
                        setGone(holder.btnUndo);
                        holder.tvName.setTextColor(dataItem.color);
                        holder.tvSub.setTextColor(dataItem.color);
                        CompatUtil.setFilterWithColor((ImageView) holder.btnAlarm, dataItem.color);
                        CompatUtil.setFilterWithColor((ImageView) holder.btnArrange, dataItem.color);
                    }

                    String subInfo = null;
                    if (DateUtil.isBeforeToday(dataItem.startTime) && !dataItem.isComplete) {
                        subInfo = getResources().getString(R.string.delayer);
                    } else if (DateUtil.isToday(dataItem.startTime)) {
                        subInfo = getResources().getString(R.string.today);
                    } else if (DateUtil.isTomorrow(dataItem.startTime)) {
                        subInfo = getResources().getString(R.string.tomorrow);
                    } else if (DateUtil.isTheDayAfterTomorrow(dataItem.startTime)) {
                        subInfo = getResources().getString(R.string.day_after_tomorrow);
                    } else if (DateUtil.isThisWeek(dataItem.startTime)) {
                        subInfo = getResources().getString(R.string.this_week) + DateUtil.getWeekDay(getResources(), dataItem.startTime);
                    } else {
                        subInfo = DateUtil.getMonthDay(dataItem.startTime);
                    }
                    holder.tvSub.setText(subInfo);
                    if (dataItem.alarm) {
                        if(LanguageUtil.isChinese()){
                            holder.tvSub.append("    提醒：" + dataItem.alermHour + "点" + dataItem.alermMinute + "分");
                        }else{
                            holder.tvSub.append("    Alarm：" + dataItem.alermHour + ":" + dataItem.alermMinute);
                        }
                    }
                }

                @Override
                public int getItemCount() {
                    return dataList.size();
                }
            });
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    closeOpendItemIfExit();
                }
            });
        }
    }


    public void loadData(List<ScheduleEvent> scheduleEvents) {
        dataList.clear();
        dataList.addAll(scheduleEvents);
        recyclerView.getAdapter().notifyDataSetChanged();
        if (dataList.isEmpty()) {
            setVisiable(R.id.no_task);
        } else {
            setGone(R.id.no_task);
        }
    }


    @Override
    public void onPause() {
        super.onPause();
        closeOpendItemIfExit();
    }

    private void closeOpendItemIfExit() {
        if (null != slideListItemWrapper) {
            slideListItemWrapper.closeMenu();
            slideListItemWrapper = null;
        }
    }

    public static QuadrantScheduleEventListFragment newInstance(Type type) {
        Bundle bundle = new Bundle();
        bundle.putInt(BUNDLE_KEY_TYPE, type.code);
        QuadrantScheduleEventListFragment scheduleEventListFragment = new QuadrantScheduleEventListFragment();
        scheduleEventListFragment.setArguments(bundle);
        return scheduleEventListFragment;
    }


    class Holder extends RecyclerView.ViewHolder {
        @Id(R.id.tv_name)
        TextView tvName;
        @Id(R.id.tv_sub)
        TextView tvSub;
        @Id(R.id.btn_delete)
        View btnDelete;
        @Id(R.id.btn_done)
        View btnComplete;
        @Id(R.id.btn_undo)
        View btnUndo;
        @Id(R.id.first_show)
        View vFirstView;
        @Id(R.id.btn_alarm)
        View btnAlarm;
        @Id(R.id.btn_edit)
        View btnEditRoutine;
        @Id(R.id.btn_arrange)
        View btnArrange;


        public Holder(View itemView) {
            super(itemView);
            InjectionUtil.loadView(itemView, this);
            vFirstView.setOnClickListener(onItemClickListener);
            SlideListItemWrapper s = (SlideListItemWrapper) itemView.findViewById(R.id.slideListItemWrapper);
            s.setSlideListener(slideListener);
            btnComplete.setOnClickListener(onCompleteBtnClickListener);
            CompatUtil.setFilterWithColorRes((ImageView) btnArrange, R.color.font_cyan);
            CompatUtil.setFilterWithColorRes((ImageView) btnAlarm, R.color.font_cyan);
            btnDelete.setOnClickListener(onDeleteBtnClickListener);
            btnUndo.setOnClickListener(onUndoBtnClickListener);
            btnAlarm.setOnClickListener(onAlarmBtnClickListener);
            btnEditRoutine.setOnClickListener(onEditBtnClickListener);
            btnArrange.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    closeOpendItemIfExit();
                    recyclerView.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if (null == satelliteMenu) {
                                satelliteMenu = new SatelliteMenu();
                            }
                            satelliteMenu.show(v, (ScheduleEvent) v.getTag());
                        }
                    }, 200);

                }
            });

        }

    }

    private final View.OnClickListener onAlarmBtnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            final ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            startActivity(PickTimeActivity.newIntent(getContext(), new WatchTimePicker.OnTimeSelectListener() {
                @Override
                public void onTimeSelected(int hour, int minute) {
                    scheduleEvent.alarm = true;
                    scheduleEvent.alermHour = hour;
                    scheduleEvent.alermMinute = minute;
                    ScheduleEventDao.replace(scheduleEvent);
                    AlarmReceiver.setAlarm(getContext().getApplicationContext(), scheduleEvent);
                    String tiemFragment;
                    if(LanguageUtil.isChinese()){
                    if (hour < 5) {
                        tiemFragment = "凌晨";
                    } else if (hour < 8) {
                        tiemFragment = "早上";
                    } else if (hour < 12) {
                        tiemFragment = "上午";
                    } else if (hour < 18) {
                        tiemFragment = "下午";
                    } else if (hour < 23) {
                        tiemFragment = "晚上";
                    } else {
                        tiemFragment = "深夜";
                    }}else{
                        tiemFragment="";
                    }
                    recyclerView.getAdapter().notifyItemChanged(dataList.indexOf(scheduleEvent));
                    String hourStr = hour < 10 ? "0" + hour : "" + hour;
                    String minuteStr = minute < 10 ? "0" + minute : "" + minute;
                    Snackbar.make(v, getResources().getString(R.string.alarm_time_that_day) + tiemFragment + hourStr + ":" + minuteStr, Snackbar.LENGTH_LONG).show();
                }
            }));
        }
    };

    private void removeItemWithUiFresh(ScheduleEvent scheduleEvent) {
        int index = dataList.indexOf(scheduleEvent);
        dataList.remove(index);
        if (dataList.isEmpty()) {
            setVisiable(R.id.no_task);
        } else {
            setGone(R.id.no_task);
        }
        recyclerView.getAdapter().notifyItemRemoved(index);
    }

    private final View.OnClickListener onItemClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            if (scheduleEvent.isRepeat) {
                int[] loc = new int[2];
                v.getLocationInWindow(loc);
                startActivity(DetailActivity.newIntent(getContext(), scheduleEvent, loc[0] + v.getWidth() / 2, loc[1] + v.getHeight() / 2));
                getActivity().overridePendingTransition(0, 0);
            } else {
                closeOpendItemIfExit();
                slideListItemWrapper = (SlideListItemWrapper) v.getParent();
                slideListItemWrapper.openMenu();
            }
        }
    };

    private final View.OnClickListener onDeleteBtnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            String toast;
            if(LanguageUtil.isChinese()) toast = "删除\"" + scheduleEvent.name + "\"的所有记录吗";
            else toast = "Delete all records of \"" +scheduleEvent.name+"\" ?";
            Snackbar snackbar = Snackbar.make(v, toast, Snackbar.LENGTH_LONG);
            snackbar.setAction(R.string.confirm, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ScheduleEventDao.delete(scheduleEvent);
                    removeItemWithUiFresh(scheduleEvent);
                }
            });
            snackbar.show();
        }
    };

    private final View.OnClickListener onCompleteBtnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            scheduleEvent.isComplete = true;
            ScheduleEventDao.replace(scheduleEvent);
            int index = dataList.indexOf(scheduleEvent);
            dataList.remove(index);
            dataList.add(scheduleEvent);
            recyclerView.getAdapter().notifyItemRemoved(index);
            recyclerView.getAdapter().notifyItemRangeInserted(dataList.size() - 1, 1);
            closeOpendItemIfExit();
        }
    };

    private final View.OnClickListener onUndoBtnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            scheduleEvent.isComplete = false;
            ScheduleEventDao.replace(scheduleEvent);
            int index = dataList.indexOf(scheduleEvent);
            dataList.remove(index);
            recyclerView.getAdapter().notifyItemRemoved(index);
            closeOpendItemIfExit();
        }
    };

    private final View.OnClickListener onEditBtnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ScheduleEvent scheduleEvent = (ScheduleEvent) v.getTag();
            int[] loc = new int[2];
            v.getLocationInWindow(loc);
            startActivity(CreateOrModifyActivity.newIntent(getContext(), scheduleEvent, loc[0] + v.getWidth() / 2, loc[1] + v.getHeight() / 2, scheduleEvent.color));
            getActivity().overridePendingTransition(0, 0);
        }
    };

    private final SlideListItemWrapper.ViewSlideListener slideListener = new SlideListItemWrapper.ViewSlideListener() {
        @Override
        public void onRightMenuSlideOut(SlideListItemWrapper v) {
            closeOpendItemIfExit();
            slideListItemWrapper = v;
        }

        @Override
        public void onLeftSlideTrigered(SlideListItemWrapper v) {
            //TODO
        }
    };

    private void updateItemUi(ScheduleEvent scheduleEvent) {
        recyclerView.getAdapter().notifyItemChanged(dataList.indexOf(scheduleEvent));
//        boolean needRemove = false;
//        switch (type) {
//            case TODAY:
//                needRemove = !DateUtil.isToday(scheduleEvent.startTime);
//                break;
//            case TOMORROW:
//                needRemove = !DateUtil.isTomorrow(scheduleEvent.startTime);
//                break;
//            case THISWEEK:
//                needRemove = !DateUtil.isThisWeek(scheduleEvent.startTime);
//                break;
//            case NEXTWEEK:
//                needRemove = !DateUtil.isNextWeek(scheduleEvent.startTime);
//                break;
//            case LATER:
//                needRemove = !DateUtil.isAfterNextWeek(scheduleEvent.startTime);
//                break;
//            case AFTERTOMORROW:
//                needRemove= !DateUtil.isTheDayAfterTomorrow(scheduleEvent.startTime);
//                break;
//        }
//        int position = dataList.indexOf(scheduleEvent);
//        if (needRemove) {
//            dataList.remove(position);
//            recyclerView.getAdapter().notifyItemRemoved(position);
//        } else {
//            recyclerView.getAdapter().notifyItemChanged(position);
//        }
    }

    class SatelliteMenu {
        private ScheduleEvent scheduleEvent;
        private final View.OnClickListener onClickTodayListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                scheduleEvent.startTime = DateUtil.getTodayStartTime();
                ScheduleEventDao.replace(scheduleEvent);
                updateItemUi(scheduleEvent);
            }
        };
        private final View.OnClickListener onClickOnedayLaterListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                scheduleEvent.startTime = Long.MAX_VALUE;
                ScheduleEventDao.replace(scheduleEvent);
                updateItemUi(scheduleEvent);
            }
        };
        SatelliteView satelliteView;
        private final View.OnClickListener onClickThisWeekListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                if (DateUtil.isTheLastDayOfWeek(DateUtil.getTodayStartTime())) {
                    Snackbar snackbar = Snackbar.make(v, R.string.snack_push_to_next_week, Snackbar.LENGTH_LONG);
                    snackbar.setAction(R.string.confirm, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            scheduleEvent.startTime = DateUtil.getTodayStartTime() + 3 * DateUtil.DAY_MILISECOND;
                            ScheduleEventDao.replace(scheduleEvent);
                            updateItemUi(scheduleEvent);
                        }
                    });
                    snackbar.show();
                } else {
                    scheduleEvent.startTime = DateUtil.getTimeLaterInThisWeek(DateUtil.getTodayStartTime());
                    ScheduleEventDao.replace(scheduleEvent);
                    updateItemUi(scheduleEvent);
                }
            }
        };
        private final View.OnClickListener onDelayToDayClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                startActivity(PickDateActivity.newIntent(getContext(), new PickDateActivity.OnDateSelectListener() {
                    @Override
                    public void onDateSelect(int year, int month, int day) {
                        satelliteView.collapse();
                        if (DateUtil.isAfterToday(year, month, day)) {
                            scheduleEvent.startTime = DateUtil.getDayStartTime(year, month, day);
                            ScheduleEventDao.replace(scheduleEvent);
                            updateItemUi(scheduleEvent);
                        } else {
                            ToastUtil.showShortToast(getResources().getString(R.string.snack_push_to_today_or_future));
                        }
                    }
                }));
            }
        };


        private final View.OnClickListener onDelayToTheDayAfterTomorrowClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                scheduleEvent.startTime = DateUtil.getTodayStartTime() + 2 * DateUtil.DAY_MILISECOND;
                ScheduleEventDao.replace(scheduleEvent);
                updateItemUi(scheduleEvent);
            }
        };
        private final View.OnClickListener onClickTororrowListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                scheduleEvent.startTime = DateUtil.getTodayStartTime() + DateUtil.DAY_MILISECOND;
                ScheduleEventDao.replace(scheduleEvent);
                updateItemUi(scheduleEvent);
            }
        };
        private final View.OnClickListener onDelayInMonthClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                satelliteView.collapse();
                if (DateUtil.isTheLastDayOfMonth(DateUtil.getTodayStartTime())) {
                    Snackbar snackbar = Snackbar.make(v, R.string.snack_push_to_next_month, Snackbar.LENGTH_LONG);
                    snackbar.setAction(R.string.confirm, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            scheduleEvent.startTime = DateUtil.getTodayStartTime() + 7 * DateUtil.DAY_MILISECOND;
                            ScheduleEventDao.replace(scheduleEvent);
                            updateItemUi(scheduleEvent);
                        }
                    });
                    snackbar.show();
                } else {
                    scheduleEvent.startTime = DateUtil.getTimeLaterInThisMonth(DateUtil.getTodayStartTime());
                    ScheduleEventDao.replace(scheduleEvent);
                    updateItemUi(scheduleEvent);
                }
            }
        };

        private SatelliteMenu() {
            satelliteView = (SatelliteView) LayoutInflater.from(getContext()).inflate(R.layout.satellite_arrange_time_layout, null);
            satelliteView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    satelliteView.collapse();
                }
            });
            satelliteView.findViewById(R.id.d_calendar).setOnClickListener(onDelayToDayClickListener);
            satelliteView.findViewById(R.id.d_day_after_tomorrow).setOnClickListener(onDelayToTheDayAfterTomorrowClickListener);
            satelliteView.findViewById(R.id.d_tomorrow).setOnClickListener(onClickTororrowListener);
            satelliteView.findViewById(R.id.d_this_month).setOnClickListener(onDelayInMonthClickListener);
            satelliteView.findViewById(R.id.d_this_week).setOnClickListener(onClickThisWeekListener);
            satelliteView.findViewById(R.id.d_today).setOnClickListener(onClickTodayListener);
            satelliteView.findViewById(R.id.d_oneday).setOnClickListener(onClickOnedayLaterListener);
        }

        public void show(View v, ScheduleEvent scheduleEvent) {
            this.scheduleEvent = scheduleEvent;
            int[] loc = new int[2];
            v.getLocationOnScreen(loc);
            int top = (int) SizeUtil.pxToDp(loc[1], getContext());
            int bottom = (int) SizeUtil.pxToDp(getResources().getDisplayMetrics().heightPixels - loc[1], getContext());
            int start = 180;
            int radius = 110;
            if (top < 140) {
                start += 60;
                radius += radius / 2;
            }
            int end = 360;
            if (bottom < 100) {
                end -= 90;
                radius += radius;
            } else if (bottom < 160) {
                end -= 60;
                radius += radius / 2;
            }
            satelliteView.expand(v, SizeUtil.dpToPx(radius, getContext()), start, end);
        }
    }

    public enum Type {
        TODAY(0), TOMORROW(1), THISWEEK(2), NEXTWEEK(3), LATER(4), ALL(5), AFTERTOMORROW(6), COMPLETE(7);

        Type(int code) {
            this.code = code;
        }

        int code;

        public static Type readType(int code) {
            switch (code) {
                case 0:
                    return TODAY;
                case 1:
                    return TOMORROW;
                case 2:
                    return THISWEEK;
                case 3:
                    return NEXTWEEK;
                case 4:
                    return LATER;
                case 5:
                    return ALL;
                case 6:
                    return AFTERTOMORROW;
                default:
                    return COMPLETE;
            }
        }
    }
}
